﻿using System;
using System.Data.SqlClient;

/// <summary>
/// Métodos necesarios para ejecutar acciones en la base de datos.
/// </summary>
public class DatabaseConnection
{
    readonly SqlConnection _myConnection;
    private readonly String _connectionString;

    // Regresa el ConnectionSrring
    public String GetConnectionString()
    {
        return _connectionString;
    }

    // Constructor de la clase
    public DatabaseConnection()
    {
        // ITESM
        _connectionString = "Data Source=mty118.mty.itesm.mx;Initial Catalog=wbecfildb;Persist Security Info=True;User ID=A00804782;Password=qsnitrop";
        
        //QUINTIS
        //_connectionString = "Data Source=SODA64-PC;Initial Catalog=wbecfildb;Integrated Security=True";

        //ELIAS
        //_connectionString = "Data Source=NONAME;Initial Catalog=wbecfildb;Integrated Security=True";
        
        _myConnection = new SqlConnection(_connectionString);
        OpenConnection();
    }


    // Genera una instancia nueva de la conexión a la base de datos
    private void OpenConnection()
    {
        try
        {
            _myConnection.Open();
        }
        catch (Exception exc)
        {
            //TODO: Insert database error message here
        }
    }


    // Cierra la instancia de la Base de Datos activa
    public void CloseConnection()
    {
        _myConnection.Close();
    }


    // Regresa un objeto SqlDataAdapter
    public SqlDataAdapter DataAdapter(SqlCommand myCommand)
    {
        myCommand.Connection = _myConnection;
        SqlDataAdapter dataAdapterObject = new SqlDataAdapter(myCommand);
        return dataAdapterObject;
    }


    // Regresa un objeto SqlDataReader del resultado de un SELECT
    public SqlDataReader ExecuteSelect(String query)
    {
        SqlCommand myCommand = new SqlCommand(query, _myConnection);
        SqlDataReader dataReader = myCommand.ExecuteReader();
        return dataReader;
    }


    // Regresa un objeto SqlDataReader del resultado de un SELECT Parametrizado
    public SqlDataReader ParameterizedExecuteSelect(SqlCommand myCommand)
    {
        myCommand.Connection = _myConnection;
        SqlDataReader dataReader = myCommand.ExecuteReader();
        return dataReader;
    }


    // Regresa el número de "rows" que se insertaron, modificaron o eliminaron
    public Int32 ExecuteNonQuery(String query)
    {
        int rowsAffected = new SqlCommand(query, _myConnection).ExecuteNonQuery();
        return rowsAffected;
    }


    // Regresa el número de "rows" que se insertaron, modificaron o eliminaron
    public Int32 ParameterizedExecuteNonQuery(SqlCommand myCommand)
    {
        myCommand.Connection = _myConnection;
        int rowsAffected = myCommand.ExecuteNonQuery();
        return rowsAffected;
    }


    // Regresa el número de "rows" que se insertaron, modificaron o eliminaron
    public Int32 ExecuteScalar(SqlCommand myCommand)
    {
        myCommand.Connection = _myConnection;
        return (Int32)myCommand.ExecuteScalar();
    }


    // Verifíca que la cuenta del usuario esté activada
    public Boolean UserValidationCheck(String matricula)
    {
        String query = "SELECT * FROM Alumnos WHERE Alumnos.Matricula = @Matricula AND Alumnos.CuentaValidada = 1";
        using (SqlCommand command = new SqlCommand(query, _myConnection))
        {
            command.Parameters.Add((new SqlParameter("@Matricula", matricula)));
            using (SqlDataReader dataReader = ParameterizedExecuteSelect(command))
            {
                return dataReader.HasRows;
            }
        }
    }


    // Regresa el estatus actual de la solicitud actual del alumno
    public void SolicitudStatus(String matricula, Int32 folioUser, ref Boolean aceptada, ref Boolean enviada, ref Boolean rechazada)
    {
        String query =
            "SELECT Solicitud.Solicitud_Aceptada, Solicitud.Solicitud_Enviada, Solicitud.Solicitud_Rechazada " +
            "FROM Solicitud WHERE Solicitud.Matricula = @Matricula AND Solicitud.Folio = @Folio";

        using (SqlCommand command = new SqlCommand(query, _myConnection))
        {
            command.Parameters.Add((new SqlParameter("@Matricula", matricula)));
            command.Parameters.Add((new SqlParameter("@Folio", folioUser)));
            using (SqlDataReader dataReader = ParameterizedExecuteSelect(command))
            {
                if(dataReader.Read())
                {
                    aceptada = (Boolean) dataReader["Solicitud_Aceptada"];
                    enviada = (Boolean)dataReader["Solicitud_Enviada"];
                    rechazada = (Boolean)dataReader["Solicitud_Rechazada"];
                }
            }
        }
    }


    // Verifica si la cuenta proporcionada existe en la base de datos
    public Boolean UserExists(String matricula, String userType)
    {
        String query;
        if(String.Equals(userType, "Alumnos"))
        {
            query = "SELECT Alumnos.Matricula FROM Alumnos WHERE Alumnos.Matricula = @ID";
        }
        else if (String.Equals(userType, "Administradores"))
        {
            query = "SELECT Administradores.Nomina FROM Administradores WHERE Administradores.Nomina = @ID";
        }
        else
        {
            return false;
        }

        using (SqlCommand command = new SqlCommand(query, _myConnection))
        {
            command.Parameters.Add((new SqlParameter("@ID", matricula)));
            using (SqlDataReader idReader = ParameterizedExecuteSelect(command))
            {
                return idReader.HasRows;
            }
        }
    }


    /* Verifica si existe un folio actual para el usuario
     * Un folio actual es aquel que no es una solicitud donde aplicó anteriormente,
     * sino la que aplicará dentro de 6 meses o 1 año.
     */
    public Boolean FolioExistsForCurrentUser(ref Int32 Folio, String Matricula)
    {
        String query = "SELECT * FROM Solicitud WHERE Solicitud.Matricula = @Matricula " +
                             "AND YEAR ( Solicitud.Solicitud_Fecha ) =  YEAR ( GETDATE() ) " +
                             "AND MONTH ( Solicitud.Solicitud_Fecha ) <= MONTH ( GETDATE() ) " +
                             "AND MONTH ( Solicitud.Solicitud_Fecha ) > (MONTH ( GETDATE() ) - 5)" +
                             "ORDER BY Solicitud.Folio DESC";

        using (SqlCommand command = new SqlCommand(query, _myConnection))
        {
            command.Parameters.Add((new SqlParameter("@Matricula", Matricula)));
            using (SqlDataReader folioReader = ParameterizedExecuteSelect(command))
            {
                if (folioReader.Read())
                {
                    String folioString = ((Int32)folioReader["Folio"]).ToString();
                    Int32.TryParse(folioString, out Folio);
                    return true;
                }
                return false;
            }
        }
    }


    // Verifica si el folio existe
    public Boolean FolioExist(Int32 folio)
    {
        String query = "SELECT Solicitud.Folio FROM Solicitud WHERE Solicitud.Folio = @Folio";

        using (SqlCommand command = new SqlCommand(query, _myConnection))
        {
            command.Parameters.Add(new SqlParameter("@Folio", folio));

            using (SqlDataReader folioReader = ParameterizedExecuteSelect(command))
            {
                if (folioReader.Read())
                {
                    if ((Int32)folioReader["Folio"] == folio)
                        return true;
                }
                return false;
            }
        }
    }


    // Verifica si el folio actual del alumno ha sido enviado
    public Boolean IsSolicitudEnviado(Int32 folio)
    {
        String query = "SELECT * FROM Solicitud WHERE Solicitud.Folio = " + folio;

        using (SqlCommand command = new SqlCommand(query, _myConnection))
        {
            using (SqlDataReader folioReader = ParameterizedExecuteSelect(command))
            {
                if (folioReader.Read())
                {
                    bool enviada = ((bool)folioReader["Solicitud_Enviada"]);
                    return enviada;
                }
                return false;
            }
        }
    }


    // Verifica si existe alguna entrada creada anteriormente para tablas fuera de Solicitud 
    public Boolean ConceptoExistsForCurrentUser(ref Int32 IdIEP, Int32 Folio, String Concepto, String tipo)
    {
        String query = "SELECT * FROM ["+tipo+"] WHERE ["+tipo+"].[Folio] = @Folio " +
                       "AND ["+tipo+"].["+tipo+"_Concepto] = @Concepto";
        

        using (SqlCommand command = new SqlCommand(query, _myConnection))
        {
            command.Parameters.Add(new SqlParameter("@Folio", Folio));
            command.Parameters.Add(new SqlParameter("@Concepto", Concepto));
            using (SqlDataReader ConceptoReader = ParameterizedExecuteSelect(command))
            {
                if (ConceptoReader.Read())
                {
                    String IdIEString = ((Int32)ConceptoReader[0]).ToString();
                    Int32.TryParse(IdIEString, out IdIEP);
                    return true;
                }
                return false;
            }
        }
    }

}